﻿using System;
using Transformable_Engine_v2.Engine.Global;

namespace Platformer_Example.Controller.Terrain
{
    public partial class BaseTerrain
    {
        public bool IsFloor
        {
            get { return Type.HasFlag(TerrainType.Floor); }
        }
        public bool IsCeiling
        {
            get { return Type.HasFlag(TerrainType.Ceiling); }
        }
        public bool IsLeftWall
        {
            get { return Type.HasFlag(TerrainType.Left); }
        }
        public bool IsRightWall
        {
            get { return Type.HasFlag(TerrainType.Right); }
        }

        public enum TerrainSprite
        {
            TopLeft,
            TopRight,
            BottomRight,
            BottomLeft,
            CornerTopRight,
            CornerTopLeft,
            CornerBottomRight,
            CornerBottomLeft,
            MiddleCenter,
            MiddleRight,
            MiddleLeft,
            TopCenter,
            BottomCenter,
            Vertical,
            Horizontal,
            RightEnd,
            TopEnd,
            BottomEnd,
            LeftEnd,
            TopLeftCorner,
            TopRightCorner,
            BottomLeftCorner,
            BottomRightCorner,
            TopWider,
            LeftWider,
            BottomWider,
            RightWider,
            Diagonal,
            Diagonal2,
            Cornered,
            BottomRightCornerTop,
            BottomLeftCornerTop,
            TopLeftCornerBottom,
            TopRightCornerBottom,
            Unknown,
            None
        }

        [Flags]
        public enum TerrainType
        {
            Left = 1,
            Floor = 2,
            Right = 4,
            Ceiling = 8,
            All = Left | Floor | Right | Ceiling,
            None = 0,
        }

        public TerrainType Type { get { return _type; } }

        static TerrainDescription TerrainFromType(int type)
        {
            switch (type)
            {
                case 137:
                case 201:
                case 153:
                case 233:
                case 169:
                case 249:
                case 217:
                    return new TerrainDescription { Sprite = TerrainSprite.TopLeft, Type = TerrainType.Floor | TerrainType.Left };
                case 76:
                case 204:
                case 108:
                case 220:
                case 92:
                case 252:
                case 236:
                    return new TerrainDescription { Sprite = TerrainSprite.TopRight, Type = TerrainType.Floor | TerrainType.Right };
                case 38:
                case 118:
                case 54:
                case 102:
                case 166:
                case 246:
                case 182:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomRight, Type = TerrainType.Ceiling | TerrainType.Right };
                case 19:
                case 179:
                case 51:
                case 147:
                case 83:
                case 243:
                case 115:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomLeft, Type = TerrainType.Ceiling | TerrainType.Left };
                case 239:
                    return new TerrainDescription { Sprite = TerrainSprite.CornerTopRight, Type = TerrainType.Floor | TerrainType.Right };
                case 223:
                    return new TerrainDescription { Sprite = TerrainSprite.CornerTopLeft, Type = TerrainType.Floor | TerrainType.Left };
                case 191:
                    return new TerrainDescription { Sprite = TerrainSprite.CornerBottomRight, Type = TerrainType.Ceiling | TerrainType.Right };
                case 127:
                    return new TerrainDescription { Sprite = TerrainSprite.CornerBottomLeft, Type = TerrainType.Ceiling | TerrainType.Left };
                case 15:
                    return new TerrainDescription { Sprite = TerrainSprite.Cornered, Type = TerrainType.All };
                case 255:
                    return new TerrainDescription { Sprite = TerrainSprite.MiddleCenter, Type = TerrainType.All };
                case 110:
                case 126:
                case 238:
                case 254:
                    return new TerrainDescription { Sprite = TerrainSprite.MiddleRight, Type = TerrainType.Right };
                case 155:
                case 187:
                case 219:
                case 251:
                    return new TerrainDescription { Sprite = TerrainSprite.MiddleLeft, Type = TerrainType.Left };
                case 205:
                case 237:
                case 221:
                    return new TerrainDescription { Sprite = TerrainSprite.TopCenter, Type = TerrainType.Floor };
                case 55:
                case 119:
                case 183:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomCenter, Type = TerrainType.Ceiling };
                case 10:
                case 26:
                case 154:
                case 106:
                case 58:
                case 202:
                case 170:
                case 74:
                case 138:
                    return new TerrainDescription { Sprite = TerrainSprite.Vertical, Type = TerrainType.Left | TerrainType.Right };
                case 5:
                case 69:
                case 37:
                case 21:
                case 133:
                case 101:
                case 149:
                    return new TerrainDescription { Sprite = TerrainSprite.Horizontal, Type = TerrainType.Floor | TerrainType.Ceiling };
                case 4:
                case 36:
                case 68:
                case 164:
                case 100:
                case 244:
                case 132:
                    return new TerrainDescription { Sprite = TerrainSprite.RightEnd, Type = TerrainType.Floor | TerrainType.Ceiling | TerrainType.Right };
                case 8:
                case 136:
                case 72:
                case 200:
                    return new TerrainDescription { Sprite = TerrainSprite.TopEnd, Type = TerrainType.Floor | TerrainType.Left | TerrainType.Right };
                case 2:
                case 18:
                case 34:
                case 50:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomEnd, Type = TerrainType.Ceiling | TerrainType.Left | TerrainType.Right };
                case 1:
                case 17:
                case 129:
                case 81:
                case 145:
                case 241:
                case 33:
                    return new TerrainDescription { Sprite = TerrainSprite.LeftEnd, Type = TerrainType.Floor | TerrainType.Ceiling | TerrainType.Left };
                case 9:
                case 73:
                case 89:
                case 25:
                case 121:
                    return new TerrainDescription { Sprite = TerrainSprite.TopLeftCorner, Type = TerrainType.Floor | TerrainType.Left };
                case 12:
                case 140:
                case 172:
                case 44:
                case 188:
                    return new TerrainDescription { Sprite = TerrainSprite.TopRightCorner, Type = TerrainType.Floor | TerrainType.Right };
                case 3:
                case 163:
                case 35:
                case 131:
                case 227:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomLeftCorner, Type = TerrainType.Ceiling | TerrainType.Left };
                case 6:
                case 86:
                case 22:
                case 70:
                case 214:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomRightCorner, Type = TerrainType.Ceiling | TerrainType.Right };
                case 63:
                    return new TerrainDescription { Sprite = TerrainSprite.TopWider, Type = TerrainType.All };
                case 111:
                    return new TerrainDescription { Sprite = TerrainSprite.LeftWider, Type = TerrainType.All };
                case 207:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomWider, Type = TerrainType.All };
                case 159:
                    return new TerrainDescription { Sprite = TerrainSprite.RightWider, Type = TerrainType.All };
                case 175:
                    return new TerrainDescription { Sprite = TerrainSprite.Diagonal, Type = TerrainType.All };
                case 105:
                case 95:
                    return new TerrainDescription { Sprite = TerrainSprite.Diagonal2, Type = TerrainType.All };
                case 215:
                case 87:
                    return new TerrainDescription { Sprite = TerrainSprite.TopLeftCornerBottom, Type = TerrainType.Ceiling };
                case 231:
                case 167:
                case 39:
                    return new TerrainDescription { Sprite = TerrainSprite.TopRightCornerBottom, Type = TerrainType.Ceiling };
                case 189:
                case 173:
                case 141:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomLeftCornerTop, Type = TerrainType.Floor };
                case 77:
                case 125:
                    return new TerrainDescription { Sprite = TerrainSprite.BottomRightCornerTop, Type = TerrainType.Floor };
                case -1:
                    //Top of stair - Has no sprite
                    return new TerrainDescription { Sprite = TerrainSprite.None, Type = TerrainType.Floor };
                default:
                    Log.LogDebug("Unknown type " + type);
                    return new TerrainDescription { Sprite = TerrainSprite.Unknown, Type = TerrainType.None };
            }
        }
    }
}